package com.cardone.platform.common.service;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.cardone.common.dto.PaginationDto;
import com.cardone.common.utils.EntityUtils;
import com.cardone.persistent.CommonDtoAttributes;
import com.cardone.platform.common.dao.AssistantDao;
import com.cardone.platform.common.dao.EntityDefaultDao;
import com.cardone.platform.common.dao.EntityExtendDao;
import com.cardone.platform.common.dao.EntityLogDao;
import com.cardone.platform.common.dao.EntityRelationshipDao;
import com.cardone.platform.common.dao.EntityTreeDao;
import com.cardone.platform.common.dto.EntityDefaultDto;
import com.cardone.platform.common.dto.EntityExtendDto;
import com.cardone.platform.common.dto.EntityLogDto;
import com.cardone.platform.common.dto.EntityRelationshipDto;
import com.cardone.platform.common.dto.EntityTreeDto;

/**
 * 辅助服务
 * 
 * @author yaoht
 * 
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class AssistantDefaultService implements AssistantService {
	/**
	 * 辅助数据持久
	 */
	private AssistantDao assistantDao;

	/**
	 * 实体与默认数据持久
	 */
	private EntityDefaultDao entityDefaultDao;

	/**
	 * 实体扩展数据持久
	 */
	private EntityExtendDao entityExtendDao;

	/**
	 * 实体日志数据持久
	 */
	private EntityLogDao entityLogDao;

	/**
	 * 实体关系数据持久
	 */
	private EntityRelationshipDao entityRelationshipDao;

	/**
	 * 实体树数据持久
	 */
	private EntityTreeDao entityTreeDao;

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityDefaultByCode(@NonNull final EntityDefaultDto deleteEntityDefault) {
		return this.entityDefaultDao.deleteByCode(deleteEntityDefault, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityDefaultByIds(@NonNull final EntityDefaultDto deleteEntityDefault) {
		return this.entityDefaultDao.deleteByIds(deleteEntityDefault);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityExtendByCode(@NonNull final EntityExtendDto deleteEntityExtend) {
		return this.entityExtendDao.deleteByCode(deleteEntityExtend, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityExtendByIds(@NonNull final EntityExtendDto deleteEntityExtend) {
		return this.entityExtendDao.deleteByIds(deleteEntityExtend);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityLogByCode(@NonNull final EntityLogDto deleteEntityLog) {
		return this.entityLogDao.deleteByCode(deleteEntityLog, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityLogByIds(@NonNull final EntityLogDto deleteEntityLog) {
		return this.entityLogDao.deleteByIds(deleteEntityLog);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityRelationshipByCode(@NonNull final EntityRelationshipDto deleteEntityRelationship) {
		return this.entityRelationshipDao.deleteByCode(deleteEntityRelationship, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityRelationshipByIds(@NonNull final EntityRelationshipDto deleteEntityRelationship) {
		return this.entityRelationshipDao.deleteByIds(deleteEntityRelationship);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityTreeByCode(@NonNull final EntityTreeDto deleteEntityTree) {
		return this.entityTreeDao.deleteByCode(deleteEntityTree, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int deleteEntityTreeByIds(@NonNull final EntityTreeDto deleteEntityTree) {
		return this.entityTreeDao.deleteByIds(deleteEntityTree);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityDefaultDto findEntityDefaultByCode(@NonNull final EntityDefaultDto findEntityDefault) {
		return this.entityDefaultDao.findByCode(EntityDefaultDto.class, findEntityDefault, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityDefaultDto findEntityDefaultById(@NonNull final EntityDefaultDto findEntityDefault) {
		return this.entityDefaultDao.findByCode(EntityDefaultDto.class, findEntityDefault, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityExtendDto findEntityExtendByCode(@NonNull final EntityExtendDto findEntityExtend) {
		return this.entityExtendDao.findByCode(EntityExtendDto.class, findEntityExtend, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityExtendDto findEntityExtendById(@NonNull final EntityExtendDto findEntityExtend) {
		return this.entityExtendDao.findByCode(EntityExtendDto.class, findEntityExtend, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityLogDto findEntityLogByCode(@NonNull final EntityLogDto findEntityLog) {
		return this.entityLogDao.findByCode(EntityLogDto.class, findEntityLog, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityLogDto findEntityLogById(@NonNull final EntityLogDto findEntityLog) {
		return this.entityLogDao.findByCode(EntityLogDto.class, findEntityLog, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityRelationshipDto findEntityRelationshipByCode(@NonNull final EntityRelationshipDto findEntityRelationship) {
		return this.entityRelationshipDao.findByCode(EntityRelationshipDto.class, findEntityRelationship, null,
		        CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityRelationshipDto findEntityRelationshipById(@NonNull final EntityRelationshipDto findEntityRelationship) {
		return this.entityRelationshipDao.findByCode(EntityRelationshipDto.class, findEntityRelationship, null,
		        CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityTreeDto findEntityTreeByCode(@NonNull final EntityTreeDto findEntityTree) {
		return this.entityTreeDao.findByCode(EntityTreeDto.class, findEntityTree, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public EntityTreeDto findEntityTreeById(@NonNull final EntityTreeDto findEntityTree) {
		return this.entityTreeDao.findByCode(EntityTreeDto.class, findEntityTree, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityDefaultDto> findListEntityDefaultByCode(@NonNull final EntityDefaultDto findListEntityDefault) {
		return this.entityDefaultDao.findListByCode(EntityDefaultDto.class, findListEntityDefault, new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityDefaultDto> findListEntityDefaultByName(@NonNull final EntityDefaultDto findListEntityDefault) {
		return this.entityDefaultDao.findListByName(EntityDefaultDto.class, findListEntityDefault);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityExtendDto> findListEntityExtendByCode(@NonNull final EntityExtendDto findListEntityExtend) {
		return this.entityExtendDao.findListByCode(EntityExtendDto.class, findListEntityExtend, new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityExtendDto> findListEntityExtendByName(@NonNull final EntityExtendDto findListEntityExtend) {
		return this.entityExtendDao.findListByName(EntityExtendDto.class, findListEntityExtend);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityLogDto> findListEntityLogByCode(@NonNull final EntityLogDto findListEntityLog) {
		return this.entityLogDao.findListByCode(EntityLogDto.class, findListEntityLog, new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityLogDto> findListEntityLogByName(@NonNull final EntityLogDto findListEntityLog) {
		return this.entityLogDao.findListByName(EntityLogDto.class, findListEntityLog);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityRelationshipDto> findListEntityRelationshipByCode(@NonNull final EntityRelationshipDto findListEntityRelationship) {
		return this.entityRelationshipDao.findListByCode(EntityRelationshipDto.class, findListEntityRelationship, new String[] {},
		        new String[] {});
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityRelationshipDto> findListEntityRelationshipByName(@NonNull final EntityRelationshipDto findListEntityRelationship) {
		return this.entityRelationshipDao.findListByName(EntityRelationshipDto.class, findListEntityRelationship);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityTreeDto> findListEntityTreeByCode(@NonNull final EntityTreeDto findListEntityTree) {
		return this.entityTreeDao.findListByCode(EntityTreeDto.class, findListEntityTree, new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<EntityTreeDto> findListEntityTreeByName(@NonNull final EntityTreeDto findListEntityTree) {
		return this.entityTreeDao.findListByName(EntityTreeDto.class, findListEntityTree);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<EntityDefaultDto> paginationEntityDefaultByCode(@NonNull final EntityDefaultDto paginationEntityDefault) {
		return this.entityDefaultDao.paginationByCode(EntityDefaultDto.class, paginationEntityDefault);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationEntityDefaultByName(@NonNull final EntityDefaultDto paginationEntityDefault) {
		return this.entityDefaultDao.paginationByName(paginationEntityDefault);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<EntityExtendDto> paginationEntityExtendByCode(@NonNull final EntityExtendDto paginationEntityExtend) {
		return this.entityExtendDao.paginationByCode(EntityExtendDto.class, paginationEntityExtend);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationEntityExtendByName(@NonNull final EntityExtendDto paginationEntityExtend) {
		return this.entityExtendDao.paginationByName(paginationEntityExtend);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<EntityLogDto> paginationEntityLogByCode(@NonNull final EntityLogDto paginationEntityLog) {
		return this.entityLogDao.paginationByCode(EntityLogDto.class, paginationEntityLog);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationEntityLogByName(@NonNull final EntityLogDto paginationEntityLog) {
		return this.entityLogDao.paginationByName(paginationEntityLog);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<EntityRelationshipDto> paginationEntityRelationshipByCode(
	        @NonNull final EntityRelationshipDto paginationEntityRelationship) {
		return this.entityRelationshipDao.paginationByCode(EntityRelationshipDto.class, paginationEntityRelationship);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationEntityRelationshipByName(
	        @NonNull final EntityRelationshipDto paginationEntityRelationship) {
		return this.entityRelationshipDao.paginationByName(paginationEntityRelationship);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<EntityTreeDto> paginationEntityTreeByCode(@NonNull final EntityTreeDto paginationEntityTree) {
		return this.entityTreeDao.paginationByCode(EntityTreeDto.class, paginationEntityTree);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationEntityTreeByName(@NonNull final EntityTreeDto paginationEntityTree) {
		return this.entityTreeDao.paginationByName(paginationEntityTree);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityDefaultByCodeNqId(@NonNull final EntityDefaultDto readEntityDefault) {
		return this.entityDefaultDao.readByCodeNqId(Integer.class, readEntityDefault);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityDefaultByName(@NonNull final EntityDefaultDto readEntityDefault) {
		return this.entityDefaultDao.readByName(Integer.class, null, readEntityDefault);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityExtendByCodeNqId(@NonNull final EntityExtendDto readEntityExtend) {
		return this.entityExtendDao.readByCodeNqId(Integer.class, readEntityExtend);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityExtendByName(@NonNull final EntityExtendDto readEntityExtend) {
		return this.entityExtendDao.readByName(Integer.class, null, readEntityExtend);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityLogByCodeNqId(@NonNull final EntityLogDto readEntityLog) {
		return this.entityLogDao.readByCodeNqId(Integer.class, readEntityLog);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityLogByName(@NonNull final EntityLogDto readEntityLog) {
		return this.entityLogDao.readByName(Integer.class, null, readEntityLog);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityRelationshipByCodeNqId(@NonNull final EntityRelationshipDto readEntityRelationship) {
		return this.entityRelationshipDao.readByCodeNqId(Integer.class, readEntityRelationship);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityRelationshipByName(@NonNull final EntityRelationshipDto readEntityRelationship) {
		return this.entityRelationshipDao.readByName(Integer.class, null, readEntityRelationship);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityTreeByCodeNqId(@NonNull final EntityTreeDto readEntityTree) {
		return this.entityTreeDao.readByCodeNqId(Integer.class, readEntityTree);
	}

	@Override
	@Cacheable(value = AssistantService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readEntityTreeByName(@NonNull final EntityTreeDto readEntityTree) {
		return this.entityTreeDao.readByName(Integer.class, null, readEntityTree);
	}

	@Override
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public void reload() {
		this.assistantDao.reload();

		this.entityDefaultDao.reload();

		this.entityLogDao.reload();

		this.entityTreeDao.reload();

		this.entityRelationshipDao.reload();

		this.entityExtendDao.reload();
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityDefaultDto saveEntityDefaultByIdOrCode(@NonNull final EntityDefaultDto saveEntityDefault) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityDefault, CommonDtoAttributes.code.name());

		final EntityDefaultDto oldEntityDefault = this.entityDefaultDao.findByCode(EntityDefaultDto.class, saveEntityDefault, null,
		        whereAndEqProperties);

		if (oldEntityDefault == null) {
			saveEntityDefault.setId(UUID.randomUUID().toString());

			this.entityDefaultDao.insertByCode(saveEntityDefault);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityDefault);

			return this.entityDefaultDao.findByCode(EntityDefaultDto.class, saveEntityDefault, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityDefault);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityDefault, oldEntityDefault,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityDefault;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityDefault);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityDefault, saveEntityDefault, notNullIdProperties);

		this.entityDefaultDao.updateByCode(saveEntityDefault, updateProperties, notNullIdProperties);

		return this.entityDefaultDao.findByCode(EntityDefaultDto.class, oldEntityDefault, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityDefaultDto saveEntityDefaultByName(@NonNull final EntityDefaultDto saveEntityDefault) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityDefault, CommonDtoAttributes.code.name());

		final EntityDefaultDto oldEntityDefault = this.entityDefaultDao.findByCode(EntityDefaultDto.class, saveEntityDefault, null,
		        whereAndEqProperties);

		if (oldEntityDefault == null) {
			saveEntityDefault.setId(UUID.randomUUID().toString());

			this.entityDefaultDao.insertByCode(saveEntityDefault);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityDefault);

			return this.entityDefaultDao.findByCode(EntityDefaultDto.class, saveEntityDefault, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityDefault);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityDefault, oldEntityDefault,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityDefault;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityDefault);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityDefault, saveEntityDefault, notNullIdProperties);

		this.entityDefaultDao.updateByCode(saveEntityDefault, updateProperties, notNullIdProperties);

		return this.entityDefaultDao.findByCode(EntityDefaultDto.class, oldEntityDefault, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityExtendDto saveEntityExtendByIdOrCode(@NonNull final EntityExtendDto saveEntityExtend) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityExtend, CommonDtoAttributes.code.name());

		final EntityExtendDto oldEntityExtend = this.entityExtendDao.findByCode(EntityExtendDto.class, saveEntityExtend, null,
		        whereAndEqProperties);

		if (oldEntityExtend == null) {
			saveEntityExtend.setId(UUID.randomUUID().toString());

			this.entityExtendDao.insertByCode(saveEntityExtend);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityExtend);

			return this.entityExtendDao.findByCode(EntityExtendDto.class, saveEntityExtend, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityExtend);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityExtend, oldEntityExtend,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityExtend;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityExtend);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityExtend, saveEntityExtend, notNullIdProperties);

		this.entityExtendDao.updateByCode(saveEntityExtend, updateProperties, notNullIdProperties);

		return this.entityExtendDao.findByCode(EntityExtendDto.class, oldEntityExtend, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityExtendDto saveEntityExtendByName(@NonNull final EntityExtendDto saveEntityExtend) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityExtend, CommonDtoAttributes.code.name());

		final EntityExtendDto oldEntityExtend = this.entityExtendDao.findByCode(EntityExtendDto.class, saveEntityExtend, null,
		        whereAndEqProperties);

		if (oldEntityExtend == null) {
			saveEntityExtend.setId(UUID.randomUUID().toString());

			this.entityExtendDao.insertByCode(saveEntityExtend);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityExtend);

			return this.entityExtendDao.findByCode(EntityExtendDto.class, saveEntityExtend, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityExtend);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityExtend, oldEntityExtend,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityExtend;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityExtend);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityExtend, saveEntityExtend, notNullIdProperties);

		this.entityExtendDao.updateByCode(saveEntityExtend, updateProperties, notNullIdProperties);

		return this.entityExtendDao.findByCode(EntityExtendDto.class, oldEntityExtend, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityLogDto saveEntityLogByIdOrCode(@NonNull final EntityLogDto saveEntityLog) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityLog, CommonDtoAttributes.code.name());

		final EntityLogDto oldEntityLog = this.entityLogDao.findByCode(EntityLogDto.class, saveEntityLog, null, whereAndEqProperties);

		if (oldEntityLog == null) {
			saveEntityLog.setId(UUID.randomUUID().toString());

			this.entityLogDao.insertByCode(saveEntityLog);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityLog);

			return this.entityLogDao.findByCode(EntityLogDto.class, saveEntityLog, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityLog);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityLog, oldEntityLog, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityLog;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityLog);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityLog, saveEntityLog, notNullIdProperties);

		this.entityLogDao.updateByCode(saveEntityLog, updateProperties, notNullIdProperties);

		return this.entityLogDao.findByCode(EntityLogDto.class, oldEntityLog, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityLogDto saveEntityLogByName(@NonNull final EntityLogDto saveEntityLog) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityLog, CommonDtoAttributes.code.name());

		final EntityLogDto oldEntityLog = this.entityLogDao.findByCode(EntityLogDto.class, saveEntityLog, null, whereAndEqProperties);

		if (oldEntityLog == null) {
			saveEntityLog.setId(UUID.randomUUID().toString());

			this.entityLogDao.insertByCode(saveEntityLog);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityLog);

			return this.entityLogDao.findByCode(EntityLogDto.class, saveEntityLog, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityLog);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityLog, oldEntityLog, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityLog;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityLog);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityLog, saveEntityLog, notNullIdProperties);

		this.entityLogDao.updateByCode(saveEntityLog, updateProperties, notNullIdProperties);

		return this.entityLogDao.findByCode(EntityLogDto.class, oldEntityLog, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityRelationshipDto saveEntityRelationshipByIdOrCode(@NonNull final EntityRelationshipDto saveEntityRelationship) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityRelationship, CommonDtoAttributes.code.name());

		final EntityRelationshipDto oldEntityRelationship = this.entityRelationshipDao.findByCode(EntityRelationshipDto.class,
		        saveEntityRelationship, null, whereAndEqProperties);

		if (oldEntityRelationship == null) {
			saveEntityRelationship.setId(UUID.randomUUID().toString());

			this.entityRelationshipDao.insertByCode(saveEntityRelationship);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityRelationship);

			return this.entityRelationshipDao
			        .findByCode(EntityRelationshipDto.class, saveEntityRelationship, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityRelationship);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityRelationship,
		        oldEntityRelationship, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityRelationship;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityRelationship);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityRelationship, saveEntityRelationship, notNullIdProperties);

		this.entityRelationshipDao.updateByCode(saveEntityRelationship, updateProperties, notNullIdProperties);

		return this.entityRelationshipDao.findByCode(EntityRelationshipDto.class, oldEntityRelationship, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityRelationshipDto saveEntityRelationshipByName(@NonNull final EntityRelationshipDto saveEntityRelationship) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityRelationship, CommonDtoAttributes.code.name());

		final EntityRelationshipDto oldEntityRelationship = this.entityRelationshipDao.findByCode(EntityRelationshipDto.class,
		        saveEntityRelationship, null, whereAndEqProperties);

		if (oldEntityRelationship == null) {
			saveEntityRelationship.setId(UUID.randomUUID().toString());

			this.entityRelationshipDao.insertByCode(saveEntityRelationship);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityRelationship);

			return this.entityRelationshipDao
			        .findByCode(EntityRelationshipDto.class, saveEntityRelationship, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityRelationship);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityRelationship,
		        oldEntityRelationship, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityRelationship;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityRelationship);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityRelationship, saveEntityRelationship, notNullIdProperties);

		this.entityRelationshipDao.updateByCode(saveEntityRelationship, updateProperties, notNullIdProperties);

		return this.entityRelationshipDao.findByCode(EntityRelationshipDto.class, oldEntityRelationship, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityTreeDto saveEntityTreeByIdOrCode(@NonNull final EntityTreeDto saveEntityTree) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityTree, CommonDtoAttributes.typeId.name(),
		        EntityTreeDao.DtoAttributes.entityId.name());

		final EntityTreeDto oldEntityTree = this.entityTreeDao.findByCode(EntityTreeDto.class, saveEntityTree, null,
		        whereAndEqProperties);

		if (oldEntityTree == null) {
			saveEntityTree.setId(UUID.randomUUID().toString());

			this.entityTreeDao.insertByCode(saveEntityTree);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityTree);

			return this.entityTreeDao.findByCode(EntityTreeDto.class, saveEntityTree, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] {
		        EntityTreeDao.DtoAttributes.entityParentId.name(), CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(),
		        CommonDtoAttributes.name.name(), CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(),
		        CommonDtoAttributes.remark.name() }, saveEntityTree);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityTree, oldEntityTree,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityTree;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityTree);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityTree, saveEntityTree, notNullIdProperties);

		this.entityTreeDao.updateByCode(saveEntityTree, updateProperties, notNullIdProperties);

		return this.entityTreeDao.findByCode(EntityTreeDto.class, oldEntityTree, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public EntityTreeDto saveEntityTreeByName(@NonNull final EntityTreeDto saveEntityTree) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(saveEntityTree, CommonDtoAttributes.code.name());

		final EntityTreeDto oldEntityTree = this.entityTreeDao.findByCode(EntityTreeDto.class, saveEntityTree, null,
		        whereAndEqProperties);

		if (oldEntityTree == null) {
			saveEntityTree.setId(UUID.randomUUID().toString());

			this.entityTreeDao.insertByCode(saveEntityTree);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(saveEntityTree);

			return this.entityTreeDao.findByCode(EntityTreeDto.class, saveEntityTree, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        saveEntityTree);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(saveEntityTree, oldEntityTree,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldEntityTree;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldEntityTree);

		com.cardone.common.utils.BeanUtils.copyProperties(oldEntityTree, saveEntityTree, notNullIdProperties);

		this.entityTreeDao.updateByCode(saveEntityTree, updateProperties, notNullIdProperties);

		return this.entityTreeDao.findByCode(EntityTreeDto.class, oldEntityTree, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityDefaultByCode(@NonNull final EntityDefaultDto updateEntityDefault) {
		return this.entityDefaultDao.updateByCode(updateEntityDefault, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityDefaultByIds(@NonNull final EntityDefaultDto updateEntityDefault) {
		return this.entityDefaultDao.updateByIds(updateEntityDefault);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityExtendByCode(@NonNull final EntityExtendDto updateEntityExtend) {
		return this.entityExtendDao.updateByCode(updateEntityExtend, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityExtendByIds(@NonNull final EntityExtendDto updateEntityExtend) {
		return this.entityExtendDao.updateByIds(updateEntityExtend);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityLogByCode(@NonNull final EntityLogDto updateEntityLog) {
		return this.entityLogDao.updateByCode(updateEntityLog, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityLogByIds(@NonNull final EntityLogDto updateEntityLog) {
		return this.entityLogDao.updateByIds(updateEntityLog);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityRelationshipByCode(@NonNull final EntityRelationshipDto updateEntityRelationship) {
		return this.entityRelationshipDao.updateByCode(updateEntityRelationship, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityRelationshipByIds(@NonNull final EntityRelationshipDto updateEntityRelationship) {
		return this.entityRelationshipDao.updateByIds(updateEntityRelationship);
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityTreeByCode(@NonNull final EntityTreeDto updateEntityTree) {
		return this.entityTreeDao.updateByCode(updateEntityTree, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = AssistantService.BEAN_ID, allEntries = true)
	public int updateEntityTreeByIds(@NonNull final EntityTreeDto updateEntityTree) {
		return this.entityTreeDao.updateByIds(updateEntityTree);
	}
}